﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>热键 - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The 热键 function creates, modifies, enables, or disables a 热键 while the script is running." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>热键</h1>

<p>在脚本运行时创建, 修改, 启用或禁用热键.</p>
<pre class="Syntax">
<span class="func">热键</span> KeyName <span class="optional">, Callback, Options</span>
</pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>KeyName</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>热键的按键的名称, 包括所有<a href="../Hotkeys.htm#Symbols">修饰符</a>. 例如, 指定 <code>#c</code> 来触发 <kbd>Win</kbd>+<kbd>C</kbd> 热键.</p>
    <p>如果 <em>KeyName</em> 已经是现有的热键, 那么将使用此函数的其他参数值更新原来的热键.</p>
    <p><em>KeyName</em> 也可以是现有的热键的名称(用双冒号语法创建), 这样会使用此函数的其他参数值更新原来的热键.</p>
    <p>指定 <em>现有的</em> 热键, <em>KeyName</em> 是不区分大小写的. 但是, 按键名称必须和现有的热键拼写相同(例如在这种情况下 Esc 与 Escape 是不同的). 此外, <a href="../Hotkeys.htm#Symbols">修饰符</a>(如 ^!+#) 的顺序是无关紧要的. <a href="GetKeyName.htm">获取按键名</a> 可用于获取标准的按键名称.</p>
    <p>热键首次创建时 -- 无论是通过 热键 函数还是脚本中的<a href="../Hotkeys.htm">双冒号语法</a> -- 其键名以及修饰符的顺序成为此热键的固定名称, 正如 <a href="../Variables.htm#ThisHotkey">内_此热键</a> 和 <em>Callback</em> 的参数所反映的那样. 这个名称由热键的所有<a href="_HotIf.htm#variant">变体</a>共享, 并且即使之后 热键  函数使用不同的修饰符顺序操作此热键, 此名称也不会改变.</p>
    <p>如果热键变体已经存在, 则根据 <em>KeyName</em> 是否包含<a href="../Hotkeys.htm#Tilde">颚化符前缀(~)</a> 更新它的行为.</p>
    <p>使用<a href="../Hotkeys.htm#prefixdollar">钩子前缀($)</a> 可添加到现有热键上. 这个前缀影响所有热键的变体且不能被删除.</p>
  </dd>

  <dt>Callback</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a>或<a href="../Concepts.htm#objects">对象</a></p>
      <p>当按下热键时, 要执行的子程序(作为一个新的<a href="../misc/Threads.htm">线程</a>). 它可以是函数名称, <a href="../objects/Functor.htm">函数对象</a>, 或不带冒号的<a href="../Hotkeys.htm">热键</a>名称.</p>
      <p>如果 <em>Callback</em> 是一个函数, 那么它的调用只有一个参数, 即热键的<a href="../Hotkeys.htm#HotBraces">名称</a>. 用<a href="../Hotkeys.htm">双冒号语法</a>定义的热键自动使用参数名 <code>ThisHotkey</code>. 热键也可以不使用热键函数而<a href="../Hotkeys.htm#Function">指定一个函数名</a>.</p>
      <p>如果 <em>Callback</em> 是热键名称, 则使用其原始函数; 具体来说, 就是对应当前 <a href="HotIf.htm">动态判断</a> 条件的热键变体的原始函数. 这通常用于恢复热键改变后的原始函数, 但也可以用于分配不同热键的函数, 前提是两个热键使用相同的 动态判断 条件.</p>
      <p>如果 <em>KeyName</em> 已经作为热键, 那么参数可以为空, 这种情况下回调不会被改变. 这在仅需要改变热键 <em>Options</em> 时很有用.</p>
      <p class="note"><strong>注意</strong>: 如果指定了函数, 但热键之前已经使用此命令禁用了, 那么热键会保持禁用状态. 要启用它, 请在 <em>Options</em> 中包含单词 ON.</p>
      <p>此参数还可以是下列特定值的其中一个:</p>
      <p><strong>On</strong>: 启用热键. 如果热键已经处于启用状态, 则不进行操作.</p>
      <p><strong>Off</strong>: 禁用热键. 如果热键已经处于禁用状态, 则不进行操作.</p>
      <p><strong>Toggle</strong>: 设置热键到相反的状态(启用或禁用).</p>
      <p><strong>AltTab</strong>(及其他): <a href="../Hotkeys.htm#alttab">这里</a>描述的特殊的 Alt-Tab 热键动作.</p>
      </dd>

  <dt>Options</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>由零个或多个下列字母组成的字符串, 字母间可以用空格分隔. 例如: <code>On B0</code>.</p>
      <p><strong>On</strong>: 如果热键当前是禁用的, 则启用它.</p>
      <p><strong>Off</strong>: 如果热键当前是启用的, 则禁用它. 此选项常用来创建初始状态为禁用的热键.</p>
      <p><strong>B</strong> 或 <strong>B0</strong>: 指定字母 B 将按照 <a href="_MaxThreadsBuffer.htm">#最大线程缓冲</a> 中描述的方法缓冲热键. 指定 B0(B 后跟着数字 0) 来禁用这种类型的缓冲.</p>
      <p><strong>Pn</strong>: 指定字母 P 后面跟着热键的<a href="../misc/Threads.htm">线程优先级</a>. 如果创建热键时省略 P 选项, 则设置优先级为 0.</p>
      <p><strong>Tn</strong>: 指定字母 T 后面跟着一个表示此热键允许的线程数, 如同 <a href="_MaxThreadsPerHotkey.htm">#单热键最大线程数</a> 中描述的那样. 例如: <code>T5</code>.</p>
      <p><strong>In</strong>(InputLevel): 指定字母 I(或 i) 后跟随热键的<a href="_InputLevel.htm">输入级别</a>. 例如: <code>I1</code>.</p>
      <p>如果任一选项字母被忽略并且热键已经存在, 这些选项将不会被更改. 但是, 如果热键还不存在 -- 也就是说, 它将由这个函数创建 -- 这些选项将默认为最近生效的那些. 例如, 如果 <a href="_MaxThreadsBuffer.htm">#最大线程缓冲</a> 出现在脚本的最底部, 也会被使用. 如果脚本中没有出现 <a href="_MaxThreadsBuffer.htm">#最大线程缓冲</a>, 那么将使用它的默认设置(在本例中为 OFF).</p>
      </dd>

</dl>

<h2 id="Error_Handling">错误处理</h2>
<p>如果参数无效或内存分配失败, 则抛出异常.</p>
<p>如果热键无效或无法创建, 则会抛出以下异常:</p>
<table class="info">
  <tr>
    <th style="white-space: nowrap">错误</th>
    <th>说明</th>
  </tr>
  <tr>
    <td>"Invalid key name."</td>
    <td><em>KeyName</em> 参数指定一个或多个当前键盘布局/语言不识别或不支持的键. <a href="Throw.htm#Exception">异常.Extra</a> 包含键名; 例如 <code>!Entre</code> 中的 "Entre".</td>
  </tr>
  <tr>
    <td>"Unsupported prefix key."</td>
    <td>例如, 不支持将鼠标滚轮作为热键 <code>WheelDown &amp; Enter</code> 的前缀. <a href="Throw.htm#Exception">异常.Extra</a> 包含前缀键.</td>
  </tr>
  <tr>
    <td>"This AltTab 热键 must have exactly one modifier/prefix."<br>
    "This AltTab 热键 must specify which key (L or R)."</td>
    <td>The <em>KeyName</em> 参数不适合与 <a href="../Hotkeys.htm#alttab">AltTab 或 ShiftAltTab</a> 动作一起使用. 需要两个键的组合. 例如: <code>RControl &amp; RShift::AltTab</code>. <a href="Throw.htm#Exception">异常.Extra</a> 包含 <em>KeyName</em>.</td>
  </tr>
  <tr>
    <td>"Nonexistent 热键."</td>
    <td>该函数试图修改一个不存在的热键. <a href="Throw.htm#Exception">异常.Extra</a> 包含 <em>KeyName</em>.</td>
  </tr>
  <tr>
    <td>"Nonexistent 热键 variant (IfWin)."</td>
    <td>该函数试图修改一个不存在的现有热键<a href="#variant">变体</a>. 要解决这个问题, 请使用 <a href="HotIf.htm">动态判断</a> 设置条件使其与要修改的热键的条件相匹配. <a href="Throw.htm#Exception">异常.Extra</a> 包含 <em>KeyName</em>.</td>
  </tr>
  <tr>
    <td>"最大值 hotkeys."</td>
    <td>创建这个热键将超过每个脚本 32762 个热键的限制(不过, 每个热键可以有无限数量的<a href="#variant">变体</a>, 而且也没有对<a href="../Hotstrings.htm">热字串</a>数量的限制).</td>
  </tr>
</table>
<p><br>
提示: <a href="Try.htm">Try</a>-<a href="Catch.htm">捕获</a> 可以用来测试是否存在热键变体.</p>
<pre>
try
    热键 "^!p"
捕获
    信息框 "The 热键 does not exist or it has no variant 遍历 the current 如果 criteria."
</pre>

<h2 id="Remarks">备注</h2>
<p><a href="HotIf.htm">当前的 动态判断  设置</a>决定了 热键 函数将操作热键的哪个<a href="#variant">变体</a>.</p>
<p>如果需要根据活动窗口的类型来自动禁用选择的热键或热字串, 使用 <code>热键 "^!c", "Off"</code> 通常不如 <a href="_HotIf.htm">#动态判断</a> 带有 <a href="WinActive.htm">窗口已激活</a>/<a href="WinExist.htm">窗口存在</a>(或它们的动态副本 <a href="HotIf.htm#IfWin">HotIfWinActive/Exist</a>) 来的方便.</p>
<p>通过<a href="../Hotkeys.htm">双冒号语法</a>创建的热键比使用 热键 函数执行地更好, 因为在脚本启动时会批量启用它们(而非一个一个地启用). 因此, 最好使用此函数仅创建那些在脚本开始运行后才知道其键名的热键. 一种此类情况是, 当通过 <a href="IniRead.htm">INI 文件</a>来配置脚本各种操作的热键时使用此函数.</p>
<p>如果脚本被<a href="Suspend.htm">挂起了</a>, 那么新增加/启用的热键也将是挂起的, 直到挂起状态被关闭(除非它们像 <a href="Suspend.htm">挂起</a> 页面中描述的那样进行了豁免).</p>
<p>如果由这个函数所做的更改是合理的将会安装或移除<a href="_InstallKeybdHook.htm">键盘</a>和/或<a href="_InstallMouseHook.htm">鼠标</a>钩子.</p>
<p>尽管 热键 函数不能直接启用或禁用其他脚本中的热键, 但在大多数情况下它可以通过创建或启用相同的热键来<a href="../misc/Override.htm">覆盖</a>它们. 这样是否有效取决于下列因素: 1) 在其他脚本中需要被覆盖的热键是否为<a href="ListHotkeys.htm">钩子热键</a>(非钩子热键总是可以成功覆盖); 2) 最近启动的热键通常优先于其他脚本中的相同热键(因此, 如果脚本是最近启动的, 那么它的覆盖应该总是会成功);  3) 此热键的启用或创建是否会重新激活<a href="_InstallKeybdHook.htm">键盘</a>或<a href="_InstallMouseHook.htm">鼠标</a>钩子(如果是, 那么覆盖总是会成功).</p>
<p>脚本中至少有一个热键时, 它会变成<a href="../Scripts.htm#persistent">持续运行的</a>, 这意味着应该使用 <a href="ExitApp.htm">退出应用</a> 而不是 退出 来终止它.</p>

<h2 id="variant">变体(副本) 热键</h2>
<p>一个特定的热键可以被创建多次, 如果每个定义有不同的 如果 条件. 这被称为 <em>热键变体</em>. 例如:</p>
<pre>动态判断窗口激活 "ahk_class Notepad"
热键 "^!c", "MyFuncForNotepad"
动态判断窗口激活  "ahk_class WordPadClass"
热键 "^!c", "MyFuncForWordPad"
动态判断窗口激活
热键 "^!c", "MyFuncForAllOtherWindows"</pre>
<p>如果有多个变体符合触发条件, 那么仅触发最早创建的那个. 这种情况的例外是全局变体(不带 如果 条件的那个): 它的优先级总是最低的, 仅当其他变体都不触发时它才会被触发.</p>
<p>创建重复热键时, <a href="../Hotkeys.htm#Symbols">修饰符</a>的顺序(如 ^!+#) 没有关系. 例如, <code>"^!c"</code> 等同于 <code>"!^c"</code>. 但是, 按键必须拼写一致. 例如, 用于此目的时, <em>Esc</em> 不同于 <em>Escape</em>(尽管大小写无关). 最后, 任何带有<a href="../Hotkeys.htm#wildcard">通配符前缀(*)</a> 的热键和不带通配符的热键是完全独立的; 例如, <code>"*F1"</code> 和 <code>"F1"</code> 都有他们各自的变体.</p>
<p>有关上下文相关的热键的更多信息, 请参阅 <a href="_HotIf.htm#general-remarks">#动态判断 的备注</a>.</p>

<h2 id="Related">相关</h2>
<p><a href="../Hotkeys.htm#Symbols">热键 Symbols</a>, <a href="HotIf.htm">动态判断</a>, <a href="../Variables.htm#ThisHotkey">内_此热键</a>, <a href="_MaxThreadsBuffer.htm">#最大线程缓冲</a>, <a href="_MaxThreadsPerHotkey.htm">#单热键最大线程数</a>, <a href="Suspend.htm">挂起</a>, <a href="IsFunc.htm">是否函数</a>, <a href="../misc/Threads.htm">线程</a>, <a href="Thread.htm">线程</a>, <a href="Critical.htm">霸体</a>, <a href="Return.htm">返回</a>, <a href="../objects/Menu.htm">Menu 对象</a>, <a href="SetTimer.htm">设置定时器</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a></p>
<pre>热键 "^!z", "MyFunc"

MyFunc(ThisHotkey)
{
    信息框 "You pressed " ThisHotkey
}</pre>
</div>

<div class="ex" id="ExOther">
<p><a href="#ExOther">#2</a>: 其他的例子</p>
<pre>热键, RCtrl &amp; RShift, AltTab <em>; 让 RCtrl &amp; RShift 执行 Alt-Tab 的功能.</em>
热键 "#c", "On"  <em>; 重新启用 Win-C 热键.</em>
热键 "$+#c", "Off"  <em>; 禁用 Shift-Win-C 热键.</em>
热键 "^!a", , "T5"  <em>; 改变热键以允许 5 个线程.</em>

动态判断窗口激活, "ahk_class Notepad"
热键 "^!c", "MyFuncForNotepad"  <em>; 创建仅在记事本中有效的热键 Ctrl-Alt-C.</em></pre>
</div>

<div class="ex" id="ExIfWin">
<p><a href="#ExIfWin">#3</a>: Create <kbd>Alt</kbd>+<kbd>W</kbd> as a 热键 that works only in Notepad.</p>
<pre>
动态判断窗口激活 "ahk_class Notepad"
热键 "!w", "ToggleWordWrap"  <em>; !w = Alt+W</em>

ToggleWordWrap(ThisHotkey)
{
    选择菜单 "A",, "Format", "Word Wrap"
}
</pre>
</div>

<div class="ex" id="ExampleIfFn">
<p><a href="#ExampleIfFn">#4</a>: 这个界面允许你注册简单的三键组合热键:</p>
<pre>
HkGui := 界面.新建()
HkGui.Add("Text", "xm", "Prefix key:")
HkGui.Add("Edit", "yp x100 w100 vPrefix", "Space")
HkGui.Add("Text", "xm", "Suffix 热键:")
HkGui.Add("Edit", "yp x100 w100 vSuffix", "f &amp; j")
HkGui.Add("Button", "Default", "Register").OnEvent("Click", "RegisterHotkey")
HkGui.OnEvent("Close", (*) =&gt; 退出应用())
HkGui.OnEvent("Escape", (*) =&gt; 退出应用())
HkGui.显示()

RegisterHotkey(thisCtrl, *)
{
    Saved := thisCtrl.Gui.Submit(false)
    动态判断 (*) =&gt; 获取按键状态(Saved.Prefix)
    热键 Saved.Suffix, (ThisHotkey) =&gt; 信息框(ThisHotkey)
}</pre>
</div>

</body>
</html>